package com.gurun.base.utils;

import android.content.Context;
import android.content.SharedPreferences;
import android.os.Environment;
import android.preference.PreferenceManager;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Map;

/**
 * SharedPreferences util
 *
 * @author harry
 */
public class SpUtils {

    public static final String LIBRARYDIR_PATH = ".gurunlibrarydirpath";
    public static final String BACKUPSP_FILENAME = "spname";

    private static Context sContext;
    private static SpUtils mInstance = null;

    private SpUtils() {
    }


    public static SpUtils getInstance(Context context) {
        sContext = context.getApplicationContext();
        if (mInstance == null) {
            synchronized (SpUtils.class) {
                if (mInstance == null) {
                    mInstance = new SpUtils();
                }
            }
        }
        return mInstance;
    }

    public Map<String, ?> getAll(String name) {
        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(sContext);
        return sp.getAll();
    }

    public void put(String key, String value) {
        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(sContext);
        SharedPreferences.Editor editor = sp.edit();
        editor.putString(key, value);
        editor.commit();
    }

    public void put(String key, int value) {
        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(sContext);
        SharedPreferences.Editor editor = sp.edit();
        editor.putInt(key, value);
        editor.commit();
    }

    public void put(String key, long value) {
        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(sContext);
        SharedPreferences.Editor editor = sp.edit();
        editor.putLong(key, value);
        editor.commit();
    }

    public void put(String key, boolean value) {
        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(sContext);
        SharedPreferences.Editor editor = sp.edit();
        editor.putBoolean(key, value);
        editor.commit();
    }

    public boolean reverse(String key, boolean defValue) {
        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(sContext);
        boolean value = sp.getBoolean(key, defValue);
        value = !value;
        SharedPreferences.Editor editor = sp.edit();
        editor.putBoolean(key, value);
        editor.commit();
        return value;
    }

    public void put(String key, float value) {
        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(sContext);
        SharedPreferences.Editor editor = sp.edit();
        editor.putFloat(key, value);
        editor.commit();
    }

    public int getInt(String key, int defValue) {
        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(sContext);
        return sp.getInt(key, defValue);
    }

    public long getLong(String key, long defValue) {
        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(sContext);
        return sp.getLong(key, defValue);
    }

    public boolean getBoolean(String key, boolean defValue) {
        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(sContext);
        return sp.getBoolean(key, defValue);
    }

    public float getFloat(String key, float defValue) {
        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(sContext);
        return sp.getFloat(key, defValue);
    }

    public String getString(String key, String defValue) {
        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(sContext);
        return sp.getString(key, defValue);
    }

    public boolean has(String key) {
        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(sContext);
        return sp.contains(key);
    }

    public void remove(String key) {
        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(sContext);
        sp.edit().remove(key).commit();
    }

    private boolean backupSharedPreferencesDataToFile(File dst) {
        boolean res = false;
        ObjectOutputStream output = null;
        try {
            output = new ObjectOutputStream(new FileOutputStream(dst));
            SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(sContext);
            output.writeObject(pref.getAll());
            res = true;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                if (output != null) {
                    output.flush();
                    output.close();
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        return res;
    }

    private boolean restoreSharedPreferencesDataFromFile(File src) {
        boolean res = false;
        ObjectInputStream input = null;
        try {
            input = new ObjectInputStream(new FileInputStream(src));
            SharedPreferences.Editor prefEdit = PreferenceManager.getDefaultSharedPreferences(sContext).edit();
            Map<String, ?> entries = (Map<String, ?>) input.readObject();
            for (Map.Entry<String, ?> entry : entries.entrySet()) {
                Object v = entry.getValue();
                String key = entry.getKey();

                if (v instanceof Boolean)
                    prefEdit.putBoolean(key, ((Boolean) v).booleanValue());
                else if (v instanceof Float)
                    prefEdit.putFloat(key, ((Float) v).floatValue());
                else if (v instanceof Integer)
                    prefEdit.putInt(key, ((Integer) v).intValue());
                else if (v instanceof Long)
                    prefEdit.putLong(key, ((Long) v).longValue());
                else if (v instanceof String)
                    prefEdit.putString(key, ((String) v));
            }
            prefEdit.commit();
            res = true;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }finally {
            try {
                if (input != null) {
                    input.close();
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        return res;
    }

    /**
     * backup sharedpreferences datas
     * @return
     */
    public boolean backupSharedPreferencesData(){
        final File dir = new File(Environment.getExternalStorageDirectory(), LIBRARYDIR_PATH);
        if (!dir.exists()){
            dir.mkdirs();
        }
        File backupFile = new File(dir.getPath(),BACKUPSP_FILENAME);
        if (!backupFile.exists()){
            try {
                backupFile.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
       return backupSharedPreferencesDataToFile(backupFile);
    }

    /**
     * restore sharedPreferences datas
     * @return
     */
    public boolean restoreSharedPreferencesData(){
        final File dir = new File(Environment.getExternalStorageDirectory(), LIBRARYDIR_PATH);
        if (!dir.exists()){
            dir.mkdirs();
        }
        File restoreFile = new File(dir.getPath(),BACKUPSP_FILENAME);
        if (restoreFile.exists()){
            return restoreSharedPreferencesDataFromFile(restoreFile);
        }

        return false;
    }
}